home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 11 - 1995 / 11.01 Jan 95 / SplittingWindowsInMacApp < prev   
Encoding:
Text File  |  1994-12-19  |  3.8 KB  |  130 lines  |  [TEXT/R*ch]

  1. Splitting Windows in MacApp
  2.  
  3. © Copyright 1995 by Tom Otvos and MacTech Magazine
  4.  
  5. ————————————————————————————————————————————————————————————————————
  6.  
  7. class TSplitterControl : public TControl
  8. {
  9. private:
  10.     TView* fFirstView;
  11.     TView* fSecondView;
  12. public:
  13.     virtual pascal void Initialize();
  14.     virtual pascal void DoMouseCommand(
  15.                                                     VPoint&         theMouse, 
  16.                                                     TToolboxEvent*     event, 
  17.                                                     CPoint             hysteresis);
  18.     virtual pascal void Draw(const VRect& area); 
  19.                                     // override
  20.         virtual pascal void SuperViewChangedFrame(
  21.                                                     const VRect&     oldFrame,  
  22.                                                     const VRect&     newFrame,  
  23.                                                     Boolean         invalidate);
  24.     virtual pascal void SetSplitViews(
  25.                                                     TView*             firstView, 
  26.                                                     TView*             secondView);
  27. };
  28.  
  29. ————————————————————————————————————————————————————————————————————
  30.  
  31. pascal void TSplitterControl::DoMouseCommand(
  32.                                                     VPoint&         theMouse, 
  33.                                                     TToolboxEvent*     event, 
  34.                                                     CPoint             hysteresis)
  35.                                                         // override
  36. {
  37.     // mouse hits in our control will immediately post a splitter
  38.     // tracker command
  39.     TSplitterTracker* splitter = new TSplitterTracker;
  40.     splitter->ISplitterTracker(fFirstView, fSecondView, this, theMouse);
  41.     this->PostCommand(splitter);
  42.     
  43.     inherited::DoMouseCommand(theMouse, event, hysteresis);
  44. }
  45.  
  46.  
  47. ————————————————————————————————————————————————————————————————————
  48.  
  49. class TSplitterTracker : public TTracker
  50. {
  51. private:
  52.     VCoordinate fDelta;
  53.     TView* fFirstView;
  54.     TView* fSecondView;
  55.     TView* fSplitter;
  56. public:
  57.     virtual pascal void ISplitterTracker(
  58.                                                     TView*             firstView, 
  59.                                                     TView*             secondView, 
  60.                                                     TView*             splitter, 
  61.                                                     VPoint&         itsMouse);
  62.     virtual pascal void TrackConstrain(
  63.                                                     TrackPhase     aTrackPhase, 
  64.                                                     const VPoint&     anchorPoint, 
  65.                                                     const VPoint&     previousPoint,
  66.                                                     VPoint&         nextPoint, 
  67.                                                     Boolean         mouseDidMove); 
  68.                                                             // override
  69.     virtual pascal void TrackFeedback(
  70.                                                     TrackPhase     aTrackPhase, 
  71.                                                     const VPoint&     anchorPoint, 
  72.                                                     const VPoint&     previousPoint,
  73.                                                     const VPoint&     nextPoint, 
  74.                                                     Boolean         mouseDidMove, 
  75.                                                     Boolean         turnItOn); 
  76.                                                         // override
  77.     virtual pascal void DoIt(); // override
  78. };
  79.  
  80. ————————————————————————————————————————————————————————————————————
  81.  
  82.     inherited::TrackConstrain(aTrackPhase, anchorPoint, 
  83.                                             previousPoint, nextPoint, 
  84.                                             mouseDidMove);
  85.     if (mouseDidMove)
  86.         // limit tracking to one direction only
  87.         nextPoint.h = previousPoint.h;
  88.  
  89. ————————————————————————————————————————————————————————————————————
  90.  
  91.     switch (aTrackPhase) {
  92.         case trackBegin:        // initialize our track delta
  93.             fDelta = 0;
  94.             break;
  95.         case trackEnd:            // how far did we go?
  96.             // anchor point is always in splitter coordinates
  97.             anchor = anchorPoint;
  98.             fSplitter->LocalToWindow(anchor);
  99.             next = nextPoint;
  100.             // next point is always in view coordinates
  101.             fView->LocalToWindow(next);
  102.             fDelta = next.v - anchor.v;
  103.             break;
  104.         }
  105.     // draw some nice feedback for the user    
  106.     PenSize(2, 2);
  107.     PenPat(&qd.gray);
  108.     fView->GetQDExtent(qdExtent);
  109.     MoveTo(qdExtent[topLeft].h, nextPoint.v);
  110.     LineTo(qdExtent[botRight].h, nextPoint.v);
  111.  
  112. ————————————————————————————————————————————————————————————————————
  113. pascal void TSplitterTracker::DoIt()
  114. {
  115.     VRect frame1, frame2;
  116.     // adjust fDelta so neither view becomes invalid
  117.     fFirstView->GetFrame(frame1);
  118.     if (fDelta < frame1.top - frame1.bottom)
  119.         fDelta = frame1.top - frame1.bottom;
  120.     fSecondView->GetFrame(frame2);
  121.     if (fDelta > frame2.bottom - frame2.top)
  122.         fDelta = frame2.bottom - frame2.top;
  123.     // adjust the first view from the bottom, the second from the top
  124.     frame1.bottom += fDelta;
  125.     fFirstView->SetFrame(frame1, kRedraw);
  126.     frame2.top += fDelta;
  127.     fSecondView->SetFrame(frame2, kRedraw);
  128. }
  129.  
  130.